

#include <algorithm>
#include <bitset>
#include <iostream>
#include "byte_decode.h"
#include "tbox_msg_prase.h"

namespace tbox_msg
{

  parse_vin::parse_vin(/* args */)
  {
  }

  parse_vin::~parse_vin()
  {
  }

  void parse_vin::parse(const std::uint8_t *bytes, const int32_t length) // VIN
  {

    development_stage_ = minor_version(bytes, length);
    vehicle_model_ = vehicle_model(bytes, length);
    major_version_ = major_version(bytes, length);
    minor_version_ = minor_version(bytes, length);
    vin_country_code_ = vin_country_code(bytes, length);
    vin_oem_ = vin_oem(bytes, length);
    vin_vehicle_type_ = vin_vehicle_type(bytes, length);
    vin_vehicle_config_ = vin_vehicle_config(bytes, length);
    vin_year_of_production_ = vin_year_of_production(bytes, length);
    vin_assembly_plant_code_ = vin_assembly_plant_code(bytes, length);
    vin_serial_number_ = vin_serial_number(bytes, length);

    majorVersion = "0" + std::to_string(major_version_);
    minorVersion = std::to_string(minor_version_);
    while (minorVersion.size() < 3)
    {
      minorVersion = "0" + minor_version_;
    }
    softwareVersion =
        devel_stage_s[development_stage_] + "-" +
        vehicle_type_s[vehicle_model_] + "-" +
        majorVersion + "-" + minorVersion;

    sequenceNum = std::to_string(vin_serial_number_);
    while (sequenceNum.size() < 5)
    {
      sequenceNum = "0" + sequenceNum;
    }

    VIN =
        vin_country_code_s[vin_country_code_] +
        vin_oem_s[vin_oem_] +
        std::to_string(vin_vehicle_type_) +
        vin_vehicle_config_s[vin_vehicle_config_] +
        std::to_string(vin_year_of_production_) +
        vin_assembly_plant_code_s[vin_assembly_plant_code_] +
        sequenceNum;
  }

  int parse_vin::major_version(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 1);
    int32_t x = t0.get_byte(0, 3);

    int32_t ret = x;
    return ret;
  }

  int parse_vin::minor_version(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 2);
    int32_t x = t0.get_byte(0, 2);

    Byte t1(bytes + 1);
    int32_t t = t1.get_byte(3, 5);

    x <<= 5;
    x |= t;

    int32_t ret = x;
    return ret;
  }

  int parse_vin::development_stage(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 0);
    int32_t x = t0.get_byte(0, 3);

    uint8_t ret = x;
    return ret;
  }

  int parse_vin::vehicle_model(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 0);
    int32_t x = t0.get_byte(3, 5);

    uint8_t ret = x;
    return ret;
  }

  int parse_vin::vin_country_code(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 2);
    int32_t x = t0.get_byte(2, 1);

    int32_t ret = x;
    return ret;
  }

  int parse_vin::vin_oem(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 2);
    int32_t x = t0.get_byte(3, 3);

    int32_t ret = x;
    return ret;
  }

  int parse_vin::vin_vehicle_type(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 3);
    int32_t x = t0.get_byte(0, 2);

    Byte t1(bytes + 2);
    int32_t t = t1.get_byte(6, 2);

    x <<= 2;
    x |= t;

    int32_t ret = x;
    return ret;
  }

  int parse_vin::vin_vehicle_config(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 3);
    int32_t x = t0.get_byte(2, 3);

    int32_t ret = x;
    return ret;
  }

  int parse_vin::vin_year_of_production(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 4);
    int32_t x = t0.get_byte(0, 3);

    Byte t1(bytes + 3);
    int32_t t = t1.get_byte(6, 2);

    x <<= 2;
    x |= t;

    int32_t ret = x;
    return ret;
  }

  int parse_vin::vin_assembly_plant_code(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 4);
    int32_t x = t0.get_byte(3, 5);

    int32_t ret = x;
    return ret;
  }

  int parse_vin::vin_serial_number(const std::uint8_t *bytes, const int32_t length)
  {
    Byte t0(bytes + 6);
    int32_t x = t0.get_byte(0, 8);

    Byte t1(bytes + 5);
    int32_t t = t1.get_byte(0, 8);

    x <<= 8;
    x |= t;

    uint32_t ret = x;
    return (int)ret;
  }
}

// int main()
// {
//   // static const char byte_v[] = "ABCDEF";
//   // std::string byT = byte_v[0],byte_v[1];
//   unsigned char byte_value[] = {0x09, 0xd3, 0x54, 0x04, 0x0e, 0xe9, 0x03, 0x01};

//   parse_can_msg::parse_vin parseVIN;
//   parseVIN.parse(byte_value, 8);

//   std::cout << "parseVIN.VIN : " << parseVIN.VIN << std::endl;
//   // printf("===%x",byte_value+1);

//   return 0;
// }